package cn.wolfcode.luowowo.controller;

import cn.wolfcode.luowowo.domain.Destination;
import cn.wolfcode.luowowo.domain.Strategy;
import cn.wolfcode.luowowo.domain.Travel;
import cn.wolfcode.luowowo.domain.UserInfo;
import cn.wolfcode.luowowo.search.domain.DestinationEs;
import cn.wolfcode.luowowo.search.domain.StrategyEs;
import cn.wolfcode.luowowo.search.domain.TravelEs;
import cn.wolfcode.luowowo.search.domain.UserInfoEs;
import cn.wolfcode.luowowo.search.query.SearchQueryObject;
import cn.wolfcode.luowowo.search.service.ISearchService;
import cn.wolfcode.luowowo.search.vo.SearchResultVO;
import cn.wolfcode.luowowo.service.IDestinationService;
import cn.wolfcode.luowowo.service.IStrategyService;
import cn.wolfcode.luowowo.service.ITravelService;
import cn.wolfcode.luowowo.service.IUserInfoService;
import cn.wolfcode.luowowo.util.JsonResult;
import cn.wolfcode.luowowo.util.ParamMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.List;

@RestController
public class SearchController {
    @Autowired
    private IDestinationService destinationService;
    @Autowired
    private ITravelService travelService;
    @Autowired
    private IStrategyService strategyService;
    @Autowired
    private IUserInfoService userInfoService;
    @Autowired
    private ISearchService searchService;

    @GetMapping("/q")
    public Object search(SearchQueryObject qo) throws UnsupportedEncodingException {
        //设置编码格式
        qo.setKeyword(URLDecoder.decode(qo.getKeyword(),"UTF-8"));
        switch (qo.getType()){
            case  SearchQueryObject.SEARCH_TYPE_DEST :
                //目的地
                return searchDest(qo);
            case  SearchQueryObject.SEARCH_TYPE_STRATEGY :
                //攻略
                return searchStrategy(qo);
            case  SearchQueryObject.SEARCH_TYPE_TRAVEL :
                //游记
                return searchTravel(qo);
            case  SearchQueryObject.SEARCH_TYPE_USER :
                //用户
                return searchUser(qo);
            default:
                //全部
                return searchAll(qo);
        }
    }

    private Object searchAll(SearchQueryObject qo) {
        SearchResultVO result = new SearchResultVO();

        Page<UserInfo> pageUserInfo = searchService.searchWithHighlight(UserInfoEs.INDEX_NAME, UserInfoEs.TYPE_NAME,
                UserInfo.class, qo, "city", "info"
        );
        Page<Travel> pageTravel = searchService.searchWithHighlight(TravelEs.INDEX_NAME, TravelEs.TYPE_NAME,
                Travel.class, qo, "title", "summary"
        );
        Page<Strategy> pageStrategy = searchService.searchWithHighlight(StrategyEs.INDEX_NAME, StrategyEs.TYPE_NAME,
                Strategy.class, qo, "title", "subTitle", "summary"
        );
        Page<Destination> pageDestination = searchService.searchWithHighlight(DestinationEs.INDEX_NAME, DestinationEs.TYPE_NAME,
                Destination.class, qo, "name", "info"
        );
        result.setUsers(pageUserInfo.getContent());
        result.setStrategys(pageStrategy.getContent());
        result.setTravels(pageTravel.getContent());
        result.setDests(pageDestination.getContent());
        result.setTotal(pageUserInfo.getTotalElements()
                +pageStrategy.getTotalElements()
                +pageTravel.getTotalElements()
                +pageDestination.getTotalElements());

        return JsonResult.success(new ParamMap().put("result",result).put("qo",qo));
    }

    private Object searchUser(SearchQueryObject qo) {
        Page<UserInfo> page = searchService.searchWithHighlight(
                UserInfoEs.INDEX_NAME,
                UserInfoEs.TYPE_NAME,
                UserInfo.class,
                qo,
                "city", "info"
        );
        return JsonResult.success(new ParamMap().put("page",page).put("qo",qo));
    }

    private Object searchTravel(SearchQueryObject qo) {
        Page<Travel> page = searchService.searchWithHighlight(
                TravelEs.INDEX_NAME,
                TravelEs.TYPE_NAME,
                Travel.class,
                qo,
                "title", "summary"
        );
        return JsonResult.success(new ParamMap().put("page",page).put("qo",qo));
    }

    private Object searchStrategy(SearchQueryObject qo) {
        /*
        * query:{
        *      multi_match:{
        *           query:"xxx"
        *           fields:["title","intro"]
        *      }
        * }
        * */
        Page<Strategy> page = searchService.searchWithHighlight(
                StrategyEs.INDEX_NAME,
                StrategyEs.TYPE_NAME,
                Strategy.class,
                qo,
                "title", "subTitle", "summary"
        );
        return JsonResult.success(new ParamMap().put("page",page).put("qo",qo));
    }

    //目的地
    private Object searchDest(SearchQueryObject qo) {

        //1:通过关键字查询目的地是否存在
        Destination dest = destinationService.getByName(qo.getKeyword());
        SearchResultVO result = new SearchResultVO();
        result.setTotal(0L);
        //如果存在
        if(dest != null){
            //2:存在: 查询指定目的地下的攻略, 游记, 用户 约定前5篇
            List<Strategy> sts = strategyService.getByDestName(qo.getKeyword());
            List<Travel> ts = travelService.getByDestName(qo.getKeyword());
            List<UserInfo> us = userInfoService.getByCity(qo.getKeyword());
            long total = sts.size()+ts.size()+us.size();
            result.setTotal(total);
            result.setUsers(us);
            result.setStrategys(sts);
            result.setTravels(ts);
        }
        //3:不存在: 提示不存在
        return JsonResult.success(new ParamMap()
                .put("result", result)
                .put("dest", dest)
                .put("qo", qo)
        );
    }
}
